﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace XQ.Framework.io.image
{

    /// <summary>
    /// 生成缩略图保存到磁盘
    /// </summary>
    public class SaveSmallImage
    {
        private Bitmap bm = null;
        private Graphics g = null;
        //原始图片
        private Image img = null;
        //原图路径
        private string bigimgPath = string.Empty;
        //生成路径
        private string smallimgStorePath = string.Empty;
        //原图的尺寸
        private int w, h;
        //生成后的尺寸
        private int width, height;

        private string drawString = string.Empty;
        /// <summary>
        /// 画字符串
        /// </summary>
        public string DrawString
        {
            get { return drawString; }
            set { drawString = value; }
        }

        private string storeName = string.Empty;
        /// <summary>
        /// 存储后的名字
        /// </summary>
        public string StoreName
        {
            get { return storeName; }
            set { storeName = value; }
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="imgPath">原来图片的路径</param>
        public SaveSmallImage(string imgPath)
        {
            this.bigimgPath = imgPath;
        }

        /// <summary>
        /// 设置存储路径，比如 c:\smallpath\
        /// </summary>
        /// <param name="path"></param>
        public void setStorePath(string path)
        {
            this.smallimgStorePath = path;
            if (!smallimgStorePath.EndsWith("\\"))
            {
                smallimgStorePath += "\\";
            }
        }
        /// <summary>
        /// 设置生成的尺寸
        /// </summary>
        /// <param name="w"></param>
        /// <param name="h"></param>
        public void setWidthHeight(int w, int h)
        {
            this.width = w;
            this.height = h;
        }
        /// <summary>
        /// 检查是否符合上传要求
        /// </summary>
        /// <returns></returns>
        private bool check()
        {
            if (width == 0 || height == 0)
            {
                return false;
            }
            if (smallimgStorePath == string.Empty || bigimgPath == string.Empty)
            {
                return false;
            }
            return true;
        }
        private bool getNewStoreName(ref string newName)
        {
            try
            {
                if (storeName != string.Empty)
                {
                    if (File.Exists(smallimgStorePath + storeName))
                    {
                        return false;
                    }
                    else
                    {
                        return true;
                    }
                }
                string[] str = { "a","b","c","d","e","f","j","h","i","j","k","l","m",
                           "n","o","p","q","r","s","t","u","v","w","x","y","z"};
                Random ran = new Random();
                newName = new FileInfo(bigimgPath).Name;
                while (File.Exists(smallimgStorePath + newName))
                {
                    newName = str[ran.Next(str.Length)] + str[ran.Next(str.Length)] + newName;
                }
                return true;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 保存图片
        /// </summary>
        /// <returns></returns>
        public bool SaveImage()
        {
            try
            {
                //
                if (!check())
                { return false; }
                //获取新的存储名字
                getNewStoreName(ref storeName);
                string finalPath = smallimgStorePath + storeName;
                //载入原始图片
                img = Image.FromFile(bigimgPath);
                w = img.Width;
                h = img.Height;
                if (width > w)
                {
                    width = w;
                }
                if (height > h)
                {
                    height = h;
                }
                bm = new Bitmap(width, height);
                g = Graphics.FromImage(bm);
                //设置高质量插值法  
                g.InterpolationMode = InterpolationMode.HighQualityBilinear;
                //设置高质量,低速度呈现平滑程度  
                g.SmoothingMode = SmoothingMode.HighQuality;
                //清空画布并设置背景色  
                g.Clear(Color.White);
                //第一个rectangle是生成后的部分，第二个是原图所要截取的部分，
                g.DrawImage(img, new Rectangle(0, 0, width, height), new Rectangle(0, 0, w, h), GraphicsUnit.Pixel);
                if (drawString != string.Empty)
                {
                    g.DrawString(drawString, SystemFonts.DefaultFont, Brushes.Black, 2, 2);
                }
                try
                {
                    string ext = new FileInfo(finalPath).Extension.ToLower();
                    switch (ext)
                    {
                        case ".png": bm.Save(finalPath, ImageFormat.Png); break;
                        case ".jpg": bm.Save(finalPath, ImageFormat.Jpeg); break;
                        case ".gif": bm.Save(finalPath, ImageFormat.Gif); break;
                        case ".bmp": bm.Save(finalPath, ImageFormat.Bmp); break;
                        default: bm.Save(finalPath, ImageFormat.Png); break;
                    }
                    return true;
                }
                catch (Exception err)
                {
                    throw err;
                }
            }
            catch (Exception err)
            {
                throw err;
            }
            finally
            {
                if (bm != null)
                {
                    bm.Dispose();
                }
                if (g != null)
                {
                    g.Dispose();
                }
                if (img != null)
                {
                    img.Dispose();
                }
            }
        }

        #region 知识补充
        //g.DrawArc 绘制一段弧线，它表示由一对坐标、宽度和高度指定的椭圆部分。 
        //g.DrawBezier 绘制由4个Point结构定义的贝塞尔样条。
        //g.DrawBeziers 用Point结构数组绘制一系列贝塞尔样条。
        //g.DrawClosedCurve 绘制由Point结构的数组定义的闭合基数样条。
        //g.DrawCurve 绘制经过一组指定的Point结构的基数样条。 
        //g.DrawEllipse 绘制一个由边框（该边框由一对坐标、高度和宽度指定）定义的椭圆。
        //g.DrawIcon 在指定坐标处绘制由指定的 Icon 表示的图像。 
        //g.DrawIconUnstretched 绘制指定的 Icon 表示的图像，而不缩放该图像。 
        //g.DrawImage 在指定位置并且按原始大小绘制指定的 Image。 
        //g.DrawImageUnscaled 在由坐标对指定的位置，使用图像的原始物理大小绘制指定的图像。 
        //g.DrawImageUnscaledAndClipped 在不进行缩放的情况下绘制指定的图像，并在需要时剪辑该图像以适合指定的矩形。
        //g.DrawLine 绘制一条连接由坐标对指定的两个点的线条。 
        //g.DrawLines 绘制一系列连接一组 Point 结构的线段。 
        //g.DrawPath 
        //g.DrawPie 绘制一个扇形，该形状由一个坐标对、宽度、高度以及两条射线所指定的椭圆定义。
        //g.DrawPolygon 绘制由一组 Point 结构定义的多边形。 
        //g.DrawRectangle 绘制由坐标对、宽度和高度指定的矩形。
        //g.DrawRectangles 绘制一系列由 Rectangle 结构指定的矩形。 
        //g.DrawString 在指定位置并且用指定的 Brush 和 Font 对象绘制指定的文本字符串.
        #endregion
    }

    public class SaveSmallIMG
    {

        public void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height)
        {
            //获取原始图片  
            Image originalImage = Image.FromFile(originalImagePath);
            //缩略图画布宽高  
            int towidth = width;
            int toheight = height;
            //原始图片写入画布坐标和宽高(用来设置裁减溢出部分)  
            int x = 0;
            int y = 0;
            int ow = originalImage.Width;
            int oh = originalImage.Height;
            //原始图片画布,设置写入缩略图画布坐标和宽高(用来原始图片整体宽高缩放)  
            int bg_x = 0;
            int bg_y = 0;
            int bg_w = towidth;
            int bg_h = toheight;
            //倍数变量  
            double multiple = 0;
            //获取宽长的或是高长与缩略图的倍数  
            if (originalImage.Width >= originalImage.Height)
                multiple = (double)originalImage.Width / (double)width;
            else
                multiple = (double)originalImage.Height / (double)height;
            //上传的图片的宽和高小等于缩略图  
            if (ow <= width && oh <= height)
            {
                //缩略图按原始宽高  
                bg_w = originalImage.Width;
                bg_h = originalImage.Height;
                //空白部分用背景色填充  
                bg_x = Convert.ToInt32(((double)towidth - (double)ow) / 2);
                bg_y = Convert.ToInt32(((double)toheight - (double)oh) / 2);
            }
            //上传的图片的宽和高大于缩略图  
            else
            {
                //宽高按比例缩放  
                bg_w = Convert.ToInt32((double)originalImage.Width / multiple);
                bg_h = Convert.ToInt32((double)originalImage.Height / multiple);
                //空白部分用背景色填充  
                bg_y = Convert.ToInt32(((double)height - (double)bg_h) / 2);
                bg_x = Convert.ToInt32(((double)width - (double)bg_w) / 2);
            }
            //新建一个bmp图片,并设置缩略图大小.  
            System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
            //新建一个画板  
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);
            //设置高质量插值法  
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
            //设置高质量,低速度呈现平滑程度  
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            //清空画布并设置背景色  
            g.Clear(System.Drawing.ColorTranslator.FromHtml("#F2F2F2"));
            //在指定位置并且按指定大小绘制原图片的指定部分  
            //第一个System.Drawing.Rectangle是原图片的画布坐标和宽高,第二个是原图片写在画布上的坐标和宽高,最后一个参数是指定数值单位为像素  
            g.DrawImage(originalImage, new Rectangle(bg_x, bg_y, bg_w, bg_h), new Rectangle(x, y, ow, oh), GraphicsUnit.Pixel);
            try
            {
                //获取图片类型  
                string fileExtension = System.IO.Path.GetExtension(originalImagePath).ToLower();
                //按原图片类型保存缩略图片,不按原格式图片会出现模糊,锯齿等问题.  
                switch (fileExtension)
                {
                    case ".gif": bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Gif); break;
                    case ".jpg": bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Jpeg); break;
                    case ".bmp": bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Bmp); break;
                    case ".png": bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Png); break;
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                originalImage.Dispose();
                bitmap.Dispose();
                g.Dispose();
            }
        }

    }
}
